//
//	ファイル名を分解する
//
function	Bunkai( name, ele )
{
	var	pos;

	ele[0] = "";
	ele[1] = "";
	ele[2] = "";

	pos = search( name, ":" );
	if( pos >= 0 )
	{
		ele[0] = ele[0]+substr( name, pos+1);
		name = substr( name, pos-(!name)+1 );
	}
	while( TRUE )
	{
		pos = search( name, "\\" );
		if( pos < 0 )
			break;
		else
		{
			ele[0] = ele[0]+substr( name, pos+1 );
			name = substr( name, pos-(!name)+1 );
		}
	}
	pos = search( name, "." );
	if( pos < 0 )
	{
		ele[1] = name;
		ele[2] = "";
		return;
	}
	else
	{
		ele[1] = ele[1]+substr( name, pos );
		ele[2] = substr( name, pos-(!name)+1 );
	}
}

function	MakeFile( file, kakucho )
{
	var pos;
	var temp[3];

	if( substr( kakucho, 1 ) == "." )
		kakucho = substr( kakucho, ( 1- !kakucho ));
	Bunkai( file, temp );
	if( temp[2] == "" )
	{
		if( substr(file, -1) == "." )
			file = file+kakucho;
		else
			file = file+"."+kakucho;
	}
	return file;
}

//
//	カーソル位置のトリミング
//	トリミング後のカーソル位置を返す
//
function TrimCursor( prev, win_type )
{
	var v_prev[3], v_cur[3];

	Position( prev, v_prev );
	Position( cur, v_cur );
	if( win_type == WIN_XY )
	{
		if ( abs(v_prev[0] - v_cur[0]) > abs( v_prev[1] - v_cur[1] ) )
			cur = Vertex( v_cur[0], v_prev[1], v_cur[2] );
		else
			cur = Vertex( v_prev[0], v_cur[1], v_cur[2] );
	}
	else if( win_type == WIN_YZ )
	{
		if ( abs(v_prev[1] - v_cur[1]) > abs( v_prev[2] - v_cur[2] ) )
			cur = Vertex( v_cur[0], v_cur[1], v_prev[2] );
		else
			cur = Vertex( v_cur[0], v_prev[1], v_cur[2] );
	}
	else if( win_type == WIN_ZX )
	{
		if ( abs(v_prev[2] - v_cur[2]) > abs( v_prev[0] - v_cur[0] ) )
			cur = Vertex( v_prev[0], v_cur[1], v_cur[2] );
		else
			cur = Vertex( v_cur[0], v_cur[1], v_prev[2] );
	}
	return;
}

//
//	座標入力パネル
//
function InputVertex( prev )
{

	var	point[3];

	Position( prev, point );
	DlogOpen( "座標入力", 5 );
	DlogString( 0, "Ｘ座標", tostring( point[0] ), 6 );
	DlogString( 2, "Ｙ座標", tostring( point[1] ), 6 );
	DlogString( 4, "Ｚ座標", tostring( point[2] ), 6 );
	if( DlogWait() )
	{
		point[0] = atoi( DlogAnswer( 0 ));
		point[1] = atoi( DlogAnswer( 2 ));
		point[2] = atoi( DlogAnswer( 4 ));
		cur = Vertex( point[0], point[1], point[2] );
	}
	else
		return FALSE;
	return TRUE;
}

//
//	中断
//
function PopandClear( flag )
{
	PopMenu();
	Status_title = Status_org;
	DrawStatus();
	Warning();
	Clear( flag );
}

//
//	最近点
//
function _Vertex()
{
	cur = PolyVertex( Cursor(), MouseWindow() );
	Cursor( cur );
}

function _Vertex2()
{
	cur = PolyVertex( Cursor() );
	Cursor( cur );
}

//
//	面の複写
//
function _CopyPolygons( vect )
{
	var	vers, i, j, sel, sels;
	var	pos, housen, uv[2];
	var	ty, temp;

	sel = Select();
	sels = SelectPolygons();
	PolyLoadInit();
	ViewCursor( OFF );
	for( i = 0; i< sels; i++ )
	{
		PolyLoad();
		DrawCurrent( FALSE );
//		ty = PolyType();
		vers = PolyVertexs();
		for( j = 0;j< vers;j++ )
		{
			temp = PolyGetVertex( j )+vect;
			PolySetVertex( temp, j );
		}
		PolyAppend( TRUE );
		DrawCurrent( TRUE );
	}
	ViewCursor( ON );
	return sel^Select();
}

//
//	ベクトル２つ与えて、ベクトル１をベクトル２に回転する行列を返す関数
//
function CalRotMatrix( vec1, vec2 )
{
	var	ue_vec;
	var	mat;
	var	x_vec, y_vec;

	vec1 = unit( vec1);
	vec2 = unit( vec2);

	if( abs(vec2) < 0.00001 )
		return UNIT_MATRIX;
	if( abs(vec1) < 0.00001 )
		return UNIT_MATRIX;

	ue_vec = vec1*vec2;
	if( abs( ue_vec ) < 0.00001 )
	{
		if( vec1.vec2 > 0 )
			return UNIT_MATRIX;
		else
		{
			if( abs(vec1*vector(0,0,1))< 0.00001 )
				return rot( UNIT_MATRIX, AXISX, 180 );
			else
				return rot( UNIT_MATRIX, AXISZ, 180 );
		}
	}
	ue_vec = unit( ue_vec );
	x_vec = unit( ue_vec*vec1 );
	y_vec = unit( ue_vec*vec2 );
	mat = (UNIT_MATRIX/Matrix( vec1, x_vec, ue_vec, vector(0,0,0)))*Matrix( vec2, y_vec, ue_vec, vector(0,0,0));
	return mat;
}

//
//	回転行列与えて、Ｘ回転、Ｙ回転、Ｚ回転の値を返す関数（単位は度）
//
function GetRotation( mat, deg )
{
	var	v[4];
	var	i, temp1, temp2, temp3;

	v[0] = getvector( mat, 0 );
	v[1] = getvector( mat, 1 );
	v[2] = getvector( mat, 2 );
	v[3] = getvector( mat, 3 );

	for( i = 0;i<3;i++ )
		v[i] = unit(v[i]);

	temp2 = vz(v[0]);
	if( temp2 <= -1.0 )
		deg[1] = 90.0;
	else if( temp2 >= 1.0 )
		deg[1] = -90.0;
	else
		deg[1] = 180.0*asin( -temp2 )/PI;

	temp1 = 1.0 - temp2*temp2;
	if( abs(temp1) < 0.00001 )
	{
		deg[0] = 0.0;
		temp2 = abs(vx(v[1]));
		temp3 = abs(vy(v[1]));
		if( (temp2 < 0.00001) & (temp3 < 0.00001))
			deg[2] = 0.0;
		else
			deg[2] = 180.0*atan2( -vx(v[1]), vy(v[1]))/PI;
	}
	else
	{
		temp1 = sqrt( temp1 );
		temp2 = abs(vz(v[1]));
		temp3 = abs(vz(v[2]));
		if(( temp2 < 0.00001 ) & ( temp3 < 0.00001 ))
			deg[0] = 0.0;
		else
			deg[0] = 180.0*atan2( vz(v[1])/temp1, vz(v[2])/temp1 )/PI;
		temp2 = abs(vy(v[0]));
		temp3 = abs(vx(v[0]));
		if(( temp2 < 0.00001 ) & ( temp3 < 0.00001 ))
			deg[2] = 0.0;
		else
			deg[2] = 180.0*atan2( vy(v[0])/temp1, vx(v[0])/temp1 )/PI;
	}
}

//
//	グリッド値の変換関数
//
function gridconv1( n )
{
	return slider_number1[n];
}

//
//	値からスライダーの位置を返す
//
function sliderconv1( n )
{
	var i;
	for( i = 0; i< MAX_SLIDER_NUM1;i++ )
	{
		if( slider_number1[i] >= n )
			break;
	}
	if( i == MAX_SLIDER_NUM1 )
		return i-1;
	return i;
}

function gridconv2( n )
{
	return slider_number2[n];
}

//
//	値からスライダーの位置を返す
//
function sliderconv2( n )
{
	var i;
	for( i = 0; i< MAX_SLIDER_NUM2;i++ )
	{
		if( slider_number2[i] >= n )
			break;
	}
	if( i == MAX_SLIDER_NUM2 )
		return i-1;
	return i;
}

function _InputVertex()
{
	var	temp;

	cur = Cursor();
	temp = InputVertex( cur );
	if( temp == TRUE )
		Cursor( cur );
}

//
//	バウンディングボックスを使う最近点
//
function BoxNearVertex()
{
	var	temp, i, j, len, p[2];
	var	p0_pos[3], p1_pos[3];
	var	x_vec, y_vec, z_vec;
	var	pos[15];

	cur = Cursor();
	if( SelectPolygons() == 0 )
		return;
	else
		SelectBox( p );

	Position( p[0], p0_pos );
	Position( p[1], p1_pos );
	x_vec = vector( (p1_pos[0] - p0_pos[0] )/2, 0, 0 );
	y_vec = vector( 0, (p1_pos[1] - p0_pos[1] )/2, 0 );
	z_vec = vector( 0, 0, (p1_pos[2] - p0_pos[2] )/2 );
	pos[0]  = ( p[0] + p[1] )*scale( UNIT_MATRIX, 0.5, 0.5, 0.5 );
	pos[1]  = pos[0] + x_vec + y_vec + z_vec;
	pos[2]  = pos[0] + x_vec + y_vec - z_vec;
	pos[3]  = pos[0] + x_vec - y_vec + z_vec;
	pos[4]  = pos[0] + x_vec - y_vec - z_vec;
	pos[5]  = pos[0] - x_vec + y_vec + z_vec;
	pos[6]  = pos[0] - x_vec + y_vec - z_vec;
	pos[7]  = pos[0] - x_vec - y_vec + z_vec;
	pos[8]  = pos[0] - x_vec - y_vec - z_vec;
	pos[9]  = pos[0] + x_vec;
	pos[10] = pos[0] - x_vec;
	pos[11] = pos[0] + y_vec;
	pos[12] = pos[0] - y_vec;
	pos[13] = pos[0] + z_vec;
	pos[14] = pos[0] - z_vec;
	len = VertexLength2(pos[0],cur );
	j = 0;
	for( i = 1; i< 15; i++ )
	{
		temp = VertexLength2( pos[i],cur );
		if( len > temp )
		{
			len = temp;
			j = i;
		}
	}
	cur = pos[j];
	Cursor( cur );
}

//
//	面がセレクトされてないとメニュー表示しない
//
function SelectCheck()
{
	var	temp;

	temp = ( MenuEnable() & MENU_CHECK);
	if( SelectPolygons() == 0 )
		MenuEnable( temp | MENU_DISABLE );
	else
		MenuEnable( temp | MENU_ENABLE );
}

//
//	表示面が１面もないとメニュー表示しない
//
function PolyCheck()
{
	var	sel;
	var	temp;

	temp = ( MenuEnable() & MENU_CHECK );
	sel = Select();
	SelectAll( TRUE );
	if( SelectPolygons() == 0 )
	{
		polycheck_flag = OFF;
		MenuEnable( temp | MENU_DISABLE );
	}
	else
	{
		polycheck_flag = ON;
		MenuEnable( temp | MENU_ENABLE );
	}
	Select( sel );
}

function PolyFlagCheck()
{
	var	temp;

	temp = ( MenuEnable() & MENU_CHECK );
	if( polycheck_flag == ON )
		MenuEnable( temp | MENU_ENABLE );
	else
		MenuEnable( temp | MENU_DISABLE );
}

//
//	三面図を初期化＆透視図を初期化
//
function AllInit()
{
	DefaultPers();
	Center(0, 0, 0);
	cur = Cursor( Vertex(0,0,0));
	zoomsize = default_zoomsize;
	SetZoom( -zoomsize );
	StatusZoom();
	if( ButtonEnable( zoomup_id ) == BUTTON_DISABLE )
	{
		ButtonEnable( zoomup_id, BUTTON_ENABLE );
		UpdateButton( zoomup_id );
	}
	if( ButtonEnable( zoomdown_id ) == BUTTON_DISABLE )
	{
		ButtonEnable( zoomdown_id, BUTTON_ENABLE );
		UpdateButton( zoomdown_id );
	}
	Update( CLEAR );
}

//
//		選択状態の面を非選択色で書く
//
function SelectAllFalse()
{
	var	i, j;

	j = SelectPolygons();
	ViewCursor( OFF );
	PolyLoadInit();
	for( i = 0; i< j; i++ )
	{
		PolyLoad();
		DrawCurrent( FALSE );
	}
	ViewCursor( ON );
}

//
//	アトリビュートイベントの処理
//
function _AttrEvent( atrno )
{
	if( atrno < 0 )
		NewAtr();
	else if( atrno == AttrCurrent())
	{
		if(( EXPERT == TRUE ) | ( MACHINE != "WINDOWS" ))
			EditAtrParameter();
		else
			EditAtr();
	}
	else
	{
		AttrCurrent( atrno );
		UpdateAttribute();
	}
}

//
//	オブジェクトイベントの処理
//
function _ObjEvent( objno )
{
	if( objno < 0 )
		NewObject();
	else if( objno == ObjCurrent())
		EditObj();
	else
	{
		ObjCurrent( objno );
		UpdateObject();
	}
}

//
//
//
function MenuQuit()
	quit_flag = TRUE;

//
//	ステータスバーに内容を表示
//
function DrawStatus()
{
	StatusBar(Status_title[0] + " "
	        + Status_title[1] + "  "
	        + Status_title[2] + "  "
	        + Status_title[3] + "  "
	        + Status_title[4] + "  ");
}

function Check_Toshaflag()
{
	if( tosha_flag == ON )
		MenuEnable( MENU_CHECK );
	else
		MenuEnable( MENU_NOCHECK );
}

function ClearStatus()
{
	var	i;
	for( i = 0;i<MAXSTATUS;i++)
		Status_title[i] = "";
}

//
//	draw_mode のON,OFFでメニューにチェックをいれるかどうか決める
//
function CheckMode()
{
	if( draw_mode == ON )
		MenuEnable( MENU_CHECK );
	else
		MenuEnable( MENU_NOCHECK);
}

//
//	メッシュ幅表示
//
function StatusMesh()
{
	StatusBar( "ﾒｯｼｭ幅:"+tostring( mesh_grid, 4 ), StatusMesh_pos );
}

//
//	スケール表示
//
function StatusZoom()
{
	var	str;
	if( zoomsize < -1 )
		str = "1/"+tostring( -zoomsize );
	else
		str = tostring( abs(zoomsize), 4 );
	StatusBar( "ｽｹｰﾙ:"+str, StatusZoom_pos );
}

//
//	ステータスバー初期化
//
function StatusInit()
{
	StatusBarWidth( StatusMesh_pos, 12 );
	StatusBarWidth( StatusZoom_pos, 10 );
	StatusBar( "", 0 );
	StatusMesh();
	StatusZoom();
}

//
//	アトリビュートデータのコピー
//
function AttrCopy( moto, saki )
{
	var	temp1[2], temp2[2];

	AttrCode( saki, AttrCode( moto ));
	AttrCol( saki, AttrCol( moto ));
	AttrAmb( saki, AttrAmb( moto ));
	AttrDif( saki, AttrDif( moto ));
	AttrTra( saki, AttrTra( moto ));
	AttrSpc( saki, AttrSpc( moto ));
	AttrSize( saki, AttrSize( moto ));
	AttrAtt( saki, AttrAtt( moto ));
	AttrMap( saki, AttrMap( moto ));
	if( AttrMap( moto ) == TRUE )
	{
		AttrMap( saki, TRUE );
		AttrMapFile( saki, AttrMapFile( moto ));
		GetAttrMapWind( moto, temp1, temp2 );
		SetAttrMapWind( saki, temp1, temp2 );
		GetAttrMapSize( moto, temp1, temp2 );
		SetAttrMapSize( saki, temp1, temp2 );
	}
}

//
//	オブジェクト名が正しいかどうか調べる
//
function NameCheck( obj_name )
{
	var	i, temp, t;

	temp = obj_name;
	t = strtoasc( temp );
	if(	(( t >= 'A' ) & ( t <= 'Z' ))|
		(( t >= 'a' ) & ( t <= 'z' ))|
		( t == '_' ))
	{
	}
	else
		return FALSE;
	temp = substr( obj_name, (-!obj_name+1));
	for( i = 1; i< !obj_name; i++ )
	{
		t = strtoasc( temp );
		if(	(( t >= 'A' ) & ( t <= 'Z' ))|
			(( t >= 'a' ) & ( t <= 'z' ))|
			(( t >= '0' ) & ( t <= '9' ))|
			( t == '_' ))
		{
		}
		else
			return FALSE;
		temp = substr( obj_name, (-!obj_name+i+1 ));
	}
	return TRUE;
}

//
//	atrnoを与えて、使われているobjnoのリストと数を返す
//
function AtrtoObj( atrno, objlist )
{
	var	sel1, sel2;
	var	atrsel, tempsel;
	var	i, j = 0;

	sel1 = Select();
	SelectAll( TRUE );
	sel2 = Select();
	PolyInvisible( FALSE );
	SelectAttr( atrno, TRUE, SELECT_UPDATE );
	atrsel = Select();
	for( i = 0; i< Objects(); i++ )
	{
		SelectObj( i, TRUE, SELECT_UPDATE );
		tempsel = Select();
		if( SelectPolygons( atrsel & tempsel ) != 0 )
		{
			objlist[j] = i;
			j++;
		}
	}
	Select( sel2 );
	PolyInvisible( invisible_flag );
	Select( sel1 );
	return j;
}

//
//	objnoを与えて、使われているatrnoのリストと数を返す
//
function ObjtoAtr( objno, atrlist )
{
	var	sel1, sel2;
	var	objsel, tempsel;
	var	i, j = 0;

	sel1 = Select();
	SelectAll( TRUE );
	sel2 = Select();
	PolyInvisible( FALSE );
	SelectObj( objno, TRUE, SELECT_UPDATE );
	objsel = Select();
	for( i = 0; i< Attrs(); i++ )
	{
		SelectAttr( i, TRUE, SELECT_UPDATE );
		tempsel = Select();
		if( SelectPolygons( objsel & tempsel ) != 0 )
		{
			atrlist[j] = i;
			j++;
		}
	}
	Select( sel2 );
	PolyInvisible( invisible_flag );
	Select( sel1 );
	return j;
}
